{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "# 函数与Lambda表达式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#关键字参数与可变参数 \n",
    "def printinfo(arg1, *args, **kwargs):\n",
    "    print(arg1)\n",
    "    print(args) #可变参数自动封装成元组\n",
    "    print(kwargs)#关键字参数封装成字典"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "70\n",
      "(60, 50)\n",
      "{}\n"
     ]
    }
   ],
   "source": [
    "printinfo(70, 60, 50)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "70\n",
      "(60, 50)\n",
      "{'a': 1, 'b': 2}\n"
     ]
    }
   ],
   "source": [
    "printinfo(70, 60, 50, a=1, b=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "命名关键字参数，目的是限制关键字参数的名字"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "局部变量：定义在函数内部；\n",
    "全局变量：定义在函数外部；\n",
    "局部变量只能在其被声明的函数内部访问，而全局变量可以在整个程序范围内访问。\n",
    "当内部作用域想修改外部作用域的变量时，就要用到 global 和 nonlocal 关键字了。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "123\n",
      "123\n"
     ]
    }
   ],
   "source": [
    "num = 1\n",
    "def fun1():\n",
    "    global num # 需要使用 global 关键字声明\n",
    "    print(num) # 1\n",
    "    num = 123\n",
    "    print(num) # 123\n",
    "fun1()\n",
    "print(num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "outer函数在这被调用\n"
     ]
    }
   ],
   "source": [
    "def outer():\n",
    "    print('outer函数在这被调用')\n",
    "    \n",
    "    def inner():\n",
    "        print('inner函数在这被调用')\n",
    "outer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "如果在一个内部函数里对外层非全局作用域的变量进行引用，那么内部函数就被认为是闭包。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "40\n"
     ]
    }
   ],
   "source": [
    "def funX(x):\n",
    "    def funY(y):\n",
    "        return x * y\n",
    "    return funY\n",
    "i = funX(8)\n",
    "print(i(5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100\n",
      "10\n"
     ]
    }
   ],
   "source": [
    "#如果要修改闭包作用域中的变量则需要 nonlocal 关键字\n",
    "def outer():\n",
    "    num = 10\n",
    "    def inner():\n",
    "        #nonlocal num # nonlocal关键字声明\n",
    "        num = 100\n",
    "        print(num)\n",
    "    inner()\n",
    "    print(num)\n",
    "outer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100\n",
      "100\n"
     ]
    }
   ],
   "source": [
    "def outer():\n",
    "    num = 10\n",
    "    def inner():\n",
    "        nonlocal num # nonlocal关键字声明\n",
    "        num = 100\n",
    "        print(num)\n",
    "    inner()\n",
    "    print(num)\n",
    "outer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "120\n"
     ]
    }
   ],
   "source": [
    "def f(n):\n",
    "    if n == 1:   #定义最底层的数值\n",
    "        return 1\n",
    "    return n * f(n - 1)#定义递归函数 自己调用自己\n",
    "print(f(5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# lambda函数表达式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lambda a：b\n",
    "a 函数参数\n",
    "b输出一些值，本身的结果就是值，不需要return语句返回\n",
    "匿名函数拥有自己的命名空间，且不能访问自己参数列表之外或全局命名空间里的参数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def sqr(x):\n",
    "    return x ** 2\n",
    "y = [sqr(x) for x in range(10)]  #列表生成式 \n",
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[x for x in range(10)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n"
     ]
    }
   ],
   "source": [
    "lbd_sqr = lambda x: x ** 2 #匿名函数\n",
    "y = [lbd_sqr(x) for x in range(10)]\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "15\n"
     ]
    }
   ],
   "source": [
    "func = lambda *args: sum(args)\n",
    "print(func(1, 2, 3, 4, 5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[11, 12, 13]"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def f(x):\n",
    "    y = []\n",
    "    for item in x:\n",
    "        y.append(item + 10)\n",
    "    return y\n",
    "x = [1, 2, 3]\n",
    "f(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "匿名函数 常常应用于函数式编程的高阶函数 (high-order function)中，主要有两种形式：\n",
    "1. 参数是函数 (filter, map)\n",
    "2. 返回值是函数 (closure)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 4, 9, 16, 25]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(map(lambda x: x ** 2, [1, 2, 3, 4, 5]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "3 nonlocal 关键字"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "4. 分别根据每一行的首元素和尾元素大小对二维列表 a = [[6, 5], [3, 7], [2, 8]] 排序。(利用lambda表达式)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[2, 8], [3, 7], [6, 5]]"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [[6, 5], [3, 7], [2, 8]]\n",
    "sorted(a,key=lambda x:x[0],reverse= False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
